package com.tianji.jersey.subresource;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;


public class Main {

    @Path("/XmlRootElement")
    @Produces({"application/xml", "application/json"})
    @Consumes({"application/xml", "application/json"})
    public static class JAXBXmlRootElementResource {
        @POST
        public JAXBXmlRootElement post(JAXBXmlRootElement r) {
            return r;
        }
       
        @Path("{path}")
        public JAXBXmlRootElementResource getSubResource(@PathParam("path") String path) {
            return new JAXBXmlRootElementResource();
        }
    }

    @Path("/XmlType")
    @Produces({"application/xml","application/json"})
    @Consumes({"application/xml","application/json"})
    public static class JAXBXmlTypeResource {
        @POST
        public JAXBElement<JAXBXmlType> post(JAXBXmlType r) {
            return new JAXBElement<JAXBXmlType>(
                    new QName("jaxbXmlRootElement"), JAXBXmlType.class, r);
        }
       
        @Path("{path}")
        public JAXBXmlTypeResource getSubResource(@PathParam("path") String path) {
            return new JAXBXmlTypeResource();
        }
    }

    @Path("/JAXBElement")
    @Produces({"application/xml","application/json"})
    @Consumes({"application/xml","application/json"})
    public static class JAXBElementResource {
        @POST
        public JAXBElement<JAXBXmlType> post(JAXBElement<JAXBXmlType> e) {
            return e;
        }
       
        @Path("{path}")
        public JAXBElementResource getSubResource(@PathParam("path") String path) {
            return new JAXBElementResource();
        }
    }

    public static void client() throws Exception {
        Client c = Client.create();
        WebResource r = c.resource("http://localhost:9998/");
       
        JAXBXmlRootElement re;
        JAXBXmlType t;
        JAXBElement<JAXBXmlType> e;

       
        // Tests for resource JAXBXmlRootElementResource
        test(r, "XmlRootElement", "application/xml");
        test(r, "XmlRootElement/something", "application/xml");
               
        test(r, "XmlRootElement", "application/json");
        test(r, "XmlRootElement/something", "application/json");

        // Tests for resource JAXBXmlTypeResource
        test(r, "XmlType", "application/xml");
        test(r, "XmlType/something", "application/xml");
               
        test(r, "XmlType", "application/json");
        test(r, "XmlType/something", "application/json");
               
        // Tests for resource JAXBElementResource
        test(r, "JAXBElement", "application/xml");        
        test(r, "JAXBElement/something", "application/xml");

        test(r, "JAXBElement", "application/json");        
        test(r, "JAXBElement/something", "application/json");
    }

    private static void test(WebResource r, String path, String mimeType) {
        JAXBXmlRootElement re;
        JAXBXmlType t;
        JAXBElement<JAXBXmlType> e;
       
        // Tests for resource JAXBXmlRootElementResource
       
        // Send an instance of JAXBXmlRootElement
        // Receieve an instance of JAXBXmlRootElement
        re = r.path(path).type(mimeType).
                post(JAXBXmlRootElement.class, new JAXBXmlRootElement("content"));
        assertEquals("content", re.value);

        // Send an instance of JAXBXmlRootElement
        // Receieve an instance of JAXBXmlType
        t = r.path(path).type(mimeType).
                post(JAXBXmlType.class, new JAXBXmlRootElement("content"));
        assertEquals("content", re.value);
       
        // Send an instance of JAXBElement<JAXBXmlType>
        // Receieve an instance of JAXBXmlType
        t = r.path(path).type(mimeType).
                post(JAXBXmlType.class,
                new JAXBElement<JAXBXmlType>(new QName("jaxbXmlRootElement"),
                JAXBXmlType.class,
                new JAXBXmlType("content")));
        assertEquals("content", re.value);        
    }
   
    private static void assertEquals(String expected, String value) {
        if (!expected.equals(value)) {
            throw new RuntimeException("Expected " + expected + " but have " + value);
        }
    }
   
} 
